#pragma once
#include <thread>
#include <atomic>
#include "../include/detection.hpp"  //百度Paddle框架移动端部署
#include "motion.cpp"

#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#define NUM 2


//赶不及了；只能堆shit_mountain;还是不堆了

//因为线程分开之后导致多线程

//使用主循环锚定线程的开启与写入
//因为一次main循环只能接收到一次图像和处理一次结果;所以只进行一次
class img_thread
{
private:
    //每次主线程都会调用一次创建线程的访问函数
    std::unique_ptr<std::thread> thread[NUM];
    //int65535能跑二十多分钟 上溢之后从负的开始循环
    int token0=0;
    int token[NUM];
    //是否处理完成
    bool finish[NUM]={0};
public:
    cv::Mat img[NUM];
    std::shared_ptr<Detection> detection[NUM];
    long preTime;
    void init(Motion & motion)
    {
        for(int i=0;i<NUM;i++)
        {
            detection[i]=make_shared<Detection>(motion.params.model);
            detection[i]->score=motion.params.score;
            token[i]=0;
            finish[i]=0;
        }
        token0=0;
    }
    void thread_creat(int n)//n从0开始
    {
        finish[n]=false;
        token0++;
        token[n]=token0;
        thread[n]=std::make_unique<std::thread>([this,n](){ detection[n]->inference(img[n]); 
                                                        finish[n]=true;});
        thread[n]->detach();
    }
    std::vector<PredictResult> thread_ask(Mat & detection_img)
    {
        std::vector<PredictResult> results_return;
        int num=0;
        int i=0;
        double distance[3]={-1};//将数组初始化为-1（有距离就不是-1）;采用距离计数分别前后是因为计数会溢出
        for(i=0;i<NUM;i++)//获取有多少线程已经结束
        {
            if(finish[i]!=0)
            {
                distance[i]=abs(token0-token[i]);
                num++;
            }
        }
        if(num==0){//一个完成的都没有;直接退出
            return results_return;
        }else if(num==1){//只有一个完成的;直接创建不是的那个就行
            for(i=0;i<NUM;i++)
            {
                if(finish[i]!=0)
                {
auto startTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();//帧率计算
printf(">> FrameTime: %ldms | %.2ffps \n", startTime - preTime,1000.0 / (startTime - preTime));
preTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();//程序开始时间
                    img[i]=detection_img.clone();
                    results_return=detection[i]->results;
                    thread_creat(i);
                }
            }
            return results_return;
        }else{
            int ii=0;
            double value=-1;
            for(i=0;i<NUM;i++)//有多个完成的;取令牌距离最近的那个
            {
                if(distance[i]>value)
                {
                    value=distance[i];
                    ii=i;
                }
            }
auto startTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();//帧率计算
printf(">> FrameTime: %ldms | %.2ffps \n", startTime - preTime,1000.0 / (startTime - preTime));
preTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();//程序开始时间
            img[ii]=detection_img.clone();
            results_return=detection[ii]->results;
            thread_creat(ii);
        }

        return results_return;
    }
    //主循环锚定线程的写入
    void close()
    {
        bool close=false;
        int num;
        for(int i=0;i<NUM;i++)
        {
            detection[i]->results_clear();
        }
        while(true)
        {
            num=0;
            for(int j=0;j<NUM;j++)//获取有多少线程已经结束
            {
                if(finish[j]!=0)
                {
                    num++;
                }
            }
            if(num==NUM)//一个完成的都没有;直接退出
            {return;}
        }
    }
};
